/**
 * @file Patient.java
 * the description of a Patient as relevant to this project
 * 
 * @author Christopher Nostand (chn8sh)
 * @date UNKNOWN		(created)
 * @date 02 April 2011 (last updated)
 */
package aperturescience.types;

import java.io.IOException;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;

public class JSONPatient extends JSONObject implements CouchDBObject {
	public static final String LASTNAME = "lastname";
	public static final String FIRSTNAME = "firstname";
	public static final String DESCRIPTION = "description";
	public static final String STATE = "state";
	public static final String CARDIAC = "cardiacstate"; 
	public static final String RESPITORY = "respitorystate";
	public static final String MENTAL = "mentalstate";
	public static final char PREFIX = 'p';
	
	public JSONPatient() {
		super();
	}
	
	//"Last name, First name"
	/**
	 * Creates patient with a given name. See format.
	 * @param name Full name of the patient in the form: "[Last Name], [First Name]" 
	 */
	public JSONPatient(String name) {
		this(	name.substring(0, name.indexOf(',')),//last name
				name.substring(name.indexOf(',')+2, name.length()).trim(),//first name
				null);
	}
	
	/**
	 * Creates a Patient with the given name.
	 * @param lastName Last name of the patient.
	 * @param firstName First name of the patient.
	 */
	public JSONPatient(String lastName, String firstName) {
		this(lastName, firstName, null);
	}
	
	/**
	 * Creates a Patient with the given name and (short) description.
	 * @param lastName Last name of the Patient.
	 * @param firstName First name of the Patient.
	 * @param description A short description of the Patient. (No specific purpose.)
	 */
	public JSONPatient(String lastName, String firstName, String description) {
		this();
		try {
			if (lastName != null)
				super.put(LASTNAME, lastName);
			if (firstName != null)
				super.put(FIRSTNAME, firstName);
			if (description != null)
				super.put(DESCRIPTION, description);
		} catch (JSONException e) { }
	}
	
	/**
	 * Creates a patient given a JsonRepresentation.
	 * @param jsonRepresentation Creates a Patient from given JsonRepresentation.
	 * @see org.org.restlet.ext.json.JsonRepresentation
	 * @throws JSONException Malformed JsonRepresentation.
	 */
	public JSONPatient(JsonRepresentation jsonRepresentation)
	throws JSONException {
		this();
		JSONObject strip = jsonRepresentation.getJsonObject();
		for (String key : JSONObject.getNames(strip))
			super.put(key, strip.get(key));
	}
	/**
	 * Creates a patient given a Representation.
	 * @param representation Creates a Patient from given Representation.
	 * @see org.restlet.representation.Representation;
	 * @throws IOException Given Representation does not conform to JsonRepresentation standards.
	 * @throws JSONException Malformed JsonRepresentation. (Shouldn't happen. IOException should throw instead.)
	 * @see org.json.JSONException
	 */
	public JSONPatient(Representation representation) 
	throws JSONException, IOException {
		this(new JsonRepresentation(representation));
	}
	
	public String getLastName() {
		try {
			return (String) super.get(LASTNAME);
		} catch (JSONException e) {
			return null;
		}
	}

	public boolean setLastName(String lastName) {
		try {
			super.remove(LASTNAME);
			super.put(LASTNAME, lastName);
			return true;
		} catch (JSONException e) {
			return false;
		}
	}

	public String getFirstName() {
		try {
			return (String) super.get(FIRSTNAME);
		} catch (JSONException e) {
			return null;
		}
	}
	
	public boolean setFirstName(String firstName) {
		try {
			super.remove(FIRSTNAME);
			super.put(FIRSTNAME, firstName);
			return true;
		} catch (JSONException e) {
			return false;
		}
	}
	
	public String getName() {
		String last = getLastName();
		String first = getFirstName();
		if (first != null && last != null)
			return "" + getLastName() + ", " + getFirstName();
		else if (first != null)
			return first;
		else if (last != null)
			return last;
		else
			return null;
	}
	
	public boolean setName(String name) {
		try {
			super.remove(LASTNAME);
			super.put(LASTNAME, name.substring(0, name.indexOf(',')));
			super.remove(FIRSTNAME);
			super.put(FIRSTNAME, name.substring(name.indexOf(',')+2, name.length()).trim());//first name
			return true;
		} catch (JSONException e) {
			return false;
		}
	}
	
	public String getDescription() {
		try {
			return super.getString(DESCRIPTION);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (JSONException e) { }
		return null;
	}

	public boolean setDescription(String desc) {
		try {
			super.remove(DESCRIPTION);
			super.put(DESCRIPTION, desc);
		}
		catch (JSONException e) {}
		return false;
	}

	public PatientState getState() {
		return new PatientState(this.getStates());
	}

	public boolean setState(PatientState state) {
		try {
			super.remove(STATE);
			super.put(STATE, state);
			return true;
		} catch (JSONException e) {
			return false;
		}
	}

	public JSONArray getStates() {
		try {
			return super.getJSONArray(STATE);
		} catch(JSONException e) {}
		return null;
	}

	public boolean setStates(JSONArray states) {
		return this.setState(new PatientState(states));
	}

	public String getID() {
		try {
			return super.getString(ID);
		} catch (JSONException e) {
			return null;
		}
	}

	public boolean setID(String dbCounter) {
		try {
			super.remove(ID);
			super.put(ID, ""+dbCounter);
		}
		catch (JSONException e) { e.printStackTrace(); }
		return false;
	}
	
	public String getRevision() {
		try {
			return super.getString(REV);
		}
		catch (JSONException e) { }
		return null;
	}
	
	public boolean setRevision(String newRevision) {
		try {
			super.remove(REV);
			super.put(REV, newRevision);
			return true;
		} catch (JSONException e) {
			return false;
		}
	}
	
	public JSONObject getJSONObject() {
		return (JSONObject)this;
	}
	
	public JsonRepresentation getJsonRepresentation() {
		return new JsonRepresentation(this);
	}
	
	public char getIdPrefix() {
		return PREFIX;
	}

	@SuppressWarnings("unchecked")
	public Iterator<String> keyIter() {
		return super.keys();
	}
}